package com.yxhl.zoume.data.tcp;

import com.yxhl.protobuf.ServiceType;
import com.yxhl.protobuf.TcpRequest;
import com.yxhl.protobuf.TcpResponse;
import com.yxhl.zoume.data.DataConstants;
import com.yxhl.zoume.data.rxbus.RxBus;
import com.yxhl.zoume.data.tcp.event.TcpConnectionFailureEvent;
import com.yxhl.zoume.data.tcp.event.TcpConnectionSuccessEvent;

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;

/**
 * Created by Xboy on 16/6/10.
 */

public class TcpClientHandler extends ChannelInboundHandlerAdapter {

    private static final String KEY_TAG = "TcpClientHandler";

    private OnChannelListener onChannelListener;

    public TcpClientHandler(OnChannelListener onChannelListener) {
        this.onChannelListener = onChannelListener;
    }

    public TcpClientHandler() {
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        if (onChannelListener != null) {
            onChannelListener.onChannelActive();
        } else {
            //发送tcp连接成功事件
            RxBus.getInstance().send(new TcpConnectionSuccessEvent());
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        // 尝试重连
        if (!TcpClient.isHandClose) {
            final EventLoop loop = ctx.channel().eventLoop();
            loop.schedule(new Runnable() {
                @Override
                public void run() {
                    Logger.getLogger(KEY_TAG).log(Level.INFO, ":::::::: 重连中.... :::::::::");
                    if (onChannelListener != null) {
                        TcpClient.startConnect(onChannelListener);
                    } else {
                        RxBus.getInstance().send(new TcpConnectionFailureEvent());
                    }
                }
            }, DataConstants.TcpConstants.RECONNECT_DELAY, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
        if (msg instanceof TcpResponse) {
            TcpResponse response = (TcpResponse) msg;
            ServiceType serviceType = response.getServiceType();
            Logger.getLogger(KEY_TAG).log(Level.INFO, "serviceType=" + serviceType.toString());
            switch (serviceType) {
                case PING:
                    // 处理服务端心跳数据
                    ctx.channel().writeAndFlush(getHeartTcpRequest());
                    break;
                case USER_QUERY_LOC:
                    if (onChannelListener != null) {
                        onChannelListener.onChannelRead(response);
                        Logger.getLogger(KEY_TAG).log(Level.INFO, "============TCPResponse:===========" + response.toString());
                    } else {
                        // TODO: 12/21/16 数据转换后，发送RxBus
                        //RxBus.getInstance().send(new TcpLocationRenderEvent(response));
                    }
                    break;
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 获取心跳请求
     *
     * @return
     */
    private TcpRequest getHeartTcpRequest() {
        TcpRequest tcpRequest = TcpRequest.newBuilder().setServiceType(ServiceType.PING).build();
        return tcpRequest;
    }

}
